home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / scrollsr.arc / scroll.src / text0000.txt < prev   
Encoding:
Text File  |  1988-08-22  |  14.9 KB  |  446 lines

  1. Submitted-by: uunet!mcvax!philmds!leo (Leo de Wit)
  2. Posting-number: Volume 1, Issue 70
  3. Archive-name: scroll
  4.  
  5. The following program, when placed in the AUTO folder, speeds up scrolling
  6. (BIOS output only). Difference is most noticeable with relative few chars
  7. per line; speeds up full screen editors, 'more' utilities, etc.
  8. For all resolutions; not for GEM, only for TOS.
  9. The corresponding binary is sent to the moderator of comp.binaries.atari.st.
  10. The program was assembled and linked with the assembler and linker from the
  11. GST-C compiler.
  12.  
  13. For correspondence conceirning this program (bugs, questions etc.) try
  14.  
  15.       L. J. M. de Wit
  16.       Nachtegaallaan 7
  17.       5731XP Mierlo
  18.       Holland
  19.       e-mail: ..!mcvax!philmds!leo
  20.  
  21. ------------------------ s t a r t   h e r e ---------------------------------
  22. ******************************************************************************
  23. *                                                                            *
  24. *    scroll.asm  version 1.0 of 23 July 1988    (C) L.J.M. de Wit 1988       *
  25. *                                                                            *
  26. * This software may be used and distributed freely if not used commercially  *
  27. * and the originator (me) is mentioned.                                      *
  28. *                                                                            *
  29. ******************************************************************************
  30. *
  31. * NAME
  32. *    scroll - fast text scrolling
  33. *
  34. * SYNTAX
  35. *    scroll.prg
  36. *
  37. * DESCRIPTION
  38. *    Scroll provides for fast scrolling; this is achieved by using a 64K
  39. *    buffer for screen memory and changing the physical screen location therein.
  40. *    The actual changes take place at the receipt of certain escape codes or
  41. *    characters that would make the entire display scroll.
  42. *
  43. *    Scroll should be in the AUTO folder as SCROLL.PRG so that it is
  44. *    installed memory resident when the system is loaded.
  45. *
  46. * DECISIONS
  47. *    The extra storage needed grabs a 33K from your free mem, unless
  48. *    the memory cannot be reserved adjacent to the original screen memory,
  49. *    in which case 65K is needed.
  50. *    The console output vector at 4a8 is used to trap the escape codes.
  51. *    Also the bios vector had to be changed (a pity);
  52. *    this is only needed to be able to load from AUTO folders:
  53. *    the con_state vector is reinitiated when the resolution changes
  54. *    The program must reside in the current drive's AUTO folder to be able
  55. *    to find itself.
  56.  
  57.       module  scroll
  58.       section s.ccode
  59.  
  60. * character codes
  61. lf       equ   10
  62. vt       equ   11
  63. ff       equ   12
  64. cr       equ   13
  65. esc      equ   27
  66.  
  67. * scrinfo offsets
  68. maxcol   equ   0
  69. maxrow   equ   2
  70. bprow    equ   4
  71. scrad    equ   10
  72. col      equ   16
  73. row      equ   18
  74. flag     equ   38
  75.  
  76. * system variables
  77. v_bas_ad   equ   $44e
  78. con_state  equ   $4a8
  79.  
  80. * GEMDOS & (X)BIOS stuff
  81. gemdos   equ   1
  82. bios     equ   13
  83. xbios    equ   14
  84. ptermres equ   $31
  85. supexec  equ   38
  86. setexc   equ   5
  87. setscreen equ  5
  88. physbase equ   2
  89. setblock equ   $4a
  90. pexec    equ   $4b
  91.  
  92. * divers
  93. bpaglen  equ   $100
  94. textlen  equ   12
  95. datalen  equ   20
  96. bsslen   equ   28
  97. linea0   equ   $a000
  98.  
  99. scrinit
  100.       move.l   4(sp),a3          * basepage start
  101.       move.l   #bpaglen,d3       * base page length
  102.       add.l    textlen(a3),d3    * + text length
  103.       add.l    datalen(a3),d3    * + data length
  104.       add.l    bsslen(a3),d3     * + bss length
  105.       add.l    #256,d3           * + rounding length
  106.       move.w   #physbase,-(sp)
  107.       trap     #xbios
  108.       addq.l   #2,sp
  109.       move.l   d0,a4             * Start physical screen memory
  110.       dc.w     linea0
  111.       suba.w   #44,a0
  112.       lea.l    scrinfo(pc),a1
  113.       move.l   a0,(a1)           * start screen info to scrinfo
  114.       move.l   a0,a2             * and also a2
  115.       move.w   maxrow(a2),d1
  116.       addq.l   #1,d1
  117.       mulu.w   bprow(a2),d1      * screen size into d1
  118.       lea.l    8(sp),a0
  119.       cmpa.l   a4,a0
  120.       bne.s    scrinstall        * last location not start of phys. screen mem.
  121.       tst.b    128(a3)
  122.       bne.s    scrinstall        * Prog. had argument: called the second time
  123.       add.l    d1,d3             * add a screen size
  124.       sub.l    d3,a0             * this will be taken off current prog area
  125.       move.l   a0,sp
  126.       suba.l   a3,a0
  127.       move.l   a0,-(sp)
  128.       move.l   a3,-(sp)
  129.       move.w   #0,-(sp)
  130.       move.w   #setblock,-(sp)
  131.       trap     #gemdos           * Leaving just enough for next load of myself
  132.       lea.l    12(sp),sp
  133.       pea      nullstr
  134.       pea      argstr
  135.       pea      progname
  136.       move.w   #0,-(sp)
  137.       move.w   #pexec,-(sp)
  138.       trap     #gemdos           * load & exec myself with a nonzero arglist
  139.       lea.l    12(sp),sp
  140.       clr.w    -(sp)
  141.       trap     #gemdos           * finished
  142.  
  143. scrinstall
  144.       lea.l    8(sp),a0
  145.       cmpa.l   a4,a0
  146.       bne.s    notattop          * current mem not adjacent to phys. screen mem.
  147. attop
  148.       suba.l   a3,a0
  149.       move.l   a0,d3             * d3 : just all we've got
  150.       lea.l    topbase(pc),a0
  151.       move.l   a4,(a0)           * current phys screen mem becomes top base
  152.       sub.l    d1,a4
  153.       lea.l    botbase(pc),a0    * and botbase a screen 'lower'
  154.       move.l   a4,(a0)
  155.       bra.s    endcalc
  156. notattop
  157.       move.l   a3,d0
  158.       add.l    d3,d0
  159.       clr.b    d0                * Adjust for 256 byte boundary
  160.       lea.l    botbase(pc),a0
  161.       move.l   d0,(a0)           * address lowest screen
  162.       add.l    d1,d0             * a screen 'higher'
  163.       lea.l    topbase(pc),a0
  164.       move.l   d0,(a0)           * address highest screen
  165.       add.l    d1,d3             * add a screen's length to mem needed
  166.       add.l    d1,d3             * and another one
  167. endcalc
  168.       pea      setvect(pc)
  169.       move.w   #supexec,-(sp)
  170.       trap     #xbios            * set new console output vector
  171.       addq.l   #6,sp
  172.       pea      newbios(pc)
  173.       move.w   #$2d,-(sp)
  174.       move.w   #setexc,-(sp)
  175.       trap     #bios             * Set new BIOS vector
  176.       addq.l   #8,sp
  177.       lea.l    oldbios(pc),a0
  178.       move.l   d0,(a0)           * Save old one
  179.       move.l   topbase(pc),d0
  180.       move.w   #-1,-(sp)
  181.       move.l   d0,-(sp)
  182.       move.l   d0,-(sp)
  183.       move.w   #setscreen,-(sp)
  184.       trap     #xbios            * make highest screen current
  185.       lea.l    12(sp),sp
  186.       clr.w    -(sp)             * return value: 0 for success
  187.       move.l   d3,-(sp)          * # bytes to keep
  188.       move.w   #ptermres,-(sp)   * keep process
  189.       trap     #gemdos           * stops here...
  190.  
  191. * New bios routine; only sets con_state to point to newconsole if not already
  192. * saving the old value.
  193. newbios
  194.       lea.l    newconsole(pc),a0
  195.       cmpa.l   con_state,a0
  196.       beq.s    newsame
  197.       bsr      setvect           * Set con_state if it was not newconsole
  198. newsame
  199.       movea.l  oldbios(pc),a0
  200.       jmp      (a0)
  201.  
  202. * This is the routine that con_state will always point to, except
  203. * when printing characters from within the routine itself.
  204. newconsole
  205.       move.l   cvsav(pc),con_state * restore original vector
  206.       move.w   d1,-(sp)          * save character to be printed on the stack
  207.       movea.l  scrinfo(pc),a1
  208.       lea.l    hadesc(pc),a0
  209.       tst.b    (a0)
  210.       beq.s    noesc             * If previous char was not escape; else ...
  211.       sf.b     (a0)              * Reset escape flag
  212.       tst.w    row(a1)
  213.       bne.s    no_0row           * If cursor not on row 0
  214.       cmp.w    #'I',d1
  215.       bne.s    not_i             * If not ESC I
  216.       bsr      scr_down          * else scroll down
  217.       move.w   #esc,d1
  218.       bsr      charout           * and print the ESC
  219.       move.w   #'I',d1
  220.       bsr      charout           * and the I
  221.       bra      newdone
  222. not_i
  223.       cmp.w    #'L',d1
  224.       bne.s    not_l             * If not ESC L
  225.       bsr      scr_down          * else scroll down
  226.       move.w   #esc,d1
  227.       bsr      charout           * and print the ESC
  228.       move.w   #'H',d1
  229.       bsr      charout           * and a H (cursor home)
  230.       bra.s    newdone
  231. not_l
  232.       cmp.w    #'M',d1
  233.       bne.s    no_0row           * If not ESC M
  234.       move.w   #cr,d1
  235.       bsr      charout           * else print CR
  236.       move.w   #lf,d1
  237.       bsr      charout           * and LF
  238.       bsr.s    scr_up            * and scroll up
  239.       bra.s    newdone
  240. no_0row
  241.       move.w   #esc,d1           * In all other 'escape cases'
  242.       bsr      charout           * print the ESC
  243.       move.w   (sp),d1
  244.       bsr      charout           * and the current character
  245.       bra.s    newdone
  246. noesc
  247.       cmp.w    #esc,d1           * Is current char an ESC?
  248.       bne.s    nonesc
  249.       lea.l    hadesc(pc),a0
  250.       st       (a0)              * Mark the flag for 'had escape'
  251.       bra.s    newdone
  252. nonesc
  253.       move.w   maxrow(a1),d0
  254.       cmp.w    row(a1),d0
  255.       bne.s    newrest           * If not yet at bottom row of display
  256.       cmp.w    #lf,d1
  257.       beq.s    newup             * But else: If you had a LF
  258.       cmp.w    #vt,d1
  259.       beq.s    newup             * or a VT
  260.       cmp.w    #ff,d1
  261.       beq.s    newup             * or a FF
  262.       cmp.w    #' ',d1
  263.       blt.s    newrest           * or: a printing character
  264.       move.w   maxcol(a1),d0
  265.       cmp.w    col(a1),d0
  266.       bne.s    newrest           * and cursor at last column
  267.       btst     #3,flag(a1)
  268.       beq.s    newrest           * and auto wrap mode; then:
  269. newup
  270.       bsr.s    scr_up            * scroll up
  271. newrest
  272.       move.w   (sp),d1           * Print the character saved
  273.       bsr      charout
  274. newdone
  275.       addq.l   #2,sp             * Clean up stack
  276.       bsr      setvect           * Reset con_state to point to me again
  277.       rts
  278.  
  279. * Scroll up routine
  280. * Depending on current base position the new screen location is only reset
  281. * or there is an area copy as well.
  282. scr_up
  283.       movea.l  scrinfo(pc),a1
  284.       move.w   bprow(a1),d0
  285.       movea.l  v_bas_ad,a0
  286.       cmpa.l   topbase(pc),a0
  287.       bge.s    up_istop
  288.       adda.w   d0,a0             * If not at top address, simply add a row's
  289.       move.l   a0,-(sp)          * size to the current address
  290.       bsr      newscreen         * and make that the current
  291.       addq.l   #4,sp
  292.       bra.s    up_end
  293. up_istop
  294.       move.w   maxrow(a1),d1
  295.       mulu.w   d0,d1
  296.       move.l   botbase(pc),a2
  297.       move.l   a2,-(sp)          * Save copy of botbase on stack
  298.       adda.w   d0,a0
  299.       move.l   a2,a1
  300.       suba.l   a0,a1             * Difference into a1
  301.       move.l   a1,-(sp)          * Save it.
  302.       move.w   d1,-(sp)          * # bytes to be copied: all but one row
  303.       move.l   a2,-(sp)          * destination: botbase
  304.       move.l   a0,-(sp)          * source: current address + one row size
  305.       bsr      moevmem           * copy it
  306.       lea.l    10(sp),sp
  307.       move.l   (sp)+,d0          * Difference into d0
  308.       movea.l  scrinfo(pc),a1
  309.       add.l    d0,scrad(a1)      * Make up for the moevmem for cursor scrad
  310.       bsr      newscreen         * Make botbase start of new screen
  311.       addq.l   #4,sp
  312. up_end
  313.       movea.l  scrinfo(pc),a1
  314.       sub.w    #1,row(a1)        * Decrement row #
  315.       move.w   maxrow(a1),d0
  316.       mulu.w   bprow(a1),d0
  317.       move.l   v_bas_ad,a0
  318.       adda.w   d0,a0
  319.       move.l   a0,-(sp)
  320.       bsr.s    clearline         * Clear last row of display
  321.       addq.l   #4,sp
  322.       rts
  323.  
  324. scr_down
  325.       movea.l  scrinfo(pc),a1
  326.       move.w   bprow(a1),d0
  327.       movea.l  v_bas_ad,a0
  328.       cmpa.l   botbase(pc),a0
  329.       ble.s    do_istop          * If current screen already at top
  330.       suba.w   d0,a0             * Else simply subtract a row's
  331.       move.l   a0,-(sp)          * size from the current address
  332.       bsr.s    newscreen         * and make that the current
  333.       addq.l   #4,sp
  334.       bra.s    do_end
  335. do_istop
  336.       move.w   maxrow(a1),d1
  337.       mulu.w   d0,d1
  338.       move.l   topbase(pc),a2
  339.       move.l   a2,-(sp)          * Save copy of topbase on stack
  340.       adda.w   d0,a2
  341.       move.l   a2,a1
  342.       suba.l   a0,a1             * Difference into a1
  343.       move.l   a1,-(sp)          * Save it.
  344.       move.w   d1,-(sp)          * # bytes to be copied: all but one row
  345.       move.l   a2,-(sp)          * destination: topbase + one row size
  346.       move.l   a0,-(sp)          * source: current address
  347.       bsr.s    moevmem           * copy it
  348.       lea.l    10(sp),sp
  349.       move.l   (sp)+,d0          * Difference into d0
  350.       movea.l  scrinfo(pc),a1
  351.       add.l    d0,scrad(a1)      * Make up for the moevmem for cursor scrad
  352.       bsr.s    newscreen         * Make botbase start of new screen
  353.       addq.l   #4,sp
  354. do_end
  355.       movea.l  scrinfo(pc),a1
  356.       add.w    #1,row(a1)        * Increment row #
  357.       move.l   v_bas_ad,-(sp)
  358.       bsr.s    clearline         * Clear top row of display
  359.       addq.l   #4,sp
  360.       rts
  361.  
  362. clearline
  363.       movea.l  scrinfo(pc),a0
  364.       moveq.l  #0,d0
  365.       move.w   bprow(a0),d0      * # : bytes per row
  366.       asr.w    #4,d0             * / 16 doing 4 longs at a time
  367.       subq.l   #1,d0
  368.       move.l   4(sp),a0          * Memory start address of row
  369.       moveq.l  #0,d1             * Filler
  370. clrnxt
  371.       move.l   d1,(a0)+
  372.       move.l   d1,(a0)+
  373.       move.l   d1,(a0)+
  374.       move.l   d1,(a0)+
  375.       dbra     d0,clrnxt
  376.       rts
  377.  
  378. setvect
  379.       lea.l    cvsav(pc),a0
  380.       move.l   con_state,(a0)    * Save current con_state value
  381.       lea.l    newconsole(pc),a0
  382.       move.l   a0,con_state      * and make it newconsole for now
  383.       rts
  384.  
  385. newscreen
  386.       move.l   4(sp),d0          * New start address of display
  387.       move.l   d0,v_bas_ad       * into logical screen pointer
  388.       swap     d0
  389.       move.b   d0,$ffff8201      * and also
  390.       swap     d0
  391.       lsr.w    #8,d0
  392.       move.b   d0,$ffff8203      * into physical screen pointer
  393.       rts
  394.  
  395. charout
  396.       and.w   #$ff,d1            * For printing
  397.       move.l  con_state,a0       * from within newconsole
  398.       jmp     (a0)
  399.  
  400. moevmem
  401.       move.l   4(sp),a0          * Source address
  402.       move.l   8(sp),a1          * Destination address
  403.       move.w   12(sp),d0         * #
  404.       lea.l    (a0,d0.w),a2      * End of source area
  405.       cmpa.l   a1,a0
  406.       bge.s    first
  407.       cmpa.l   a2,a1
  408.       blt.s    second
  409. first
  410.       lsr.w    #4,d0             * /16, copying 4 longs at a time
  411.       sub.w    #1,d0
  412. f_next
  413.       move.l   (a0)+,(a1)+
  414.       move.l   (a0)+,(a1)+
  415.       move.l   (a0)+,(a1)+
  416.       move.l   (a0)+,(a1)+
  417.       dbra     d0,f_next         * Copy source to destination, forwards
  418.       rts
  419. second
  420.       lea.l    (a1,d0.w),a1      * End address of dest area
  421.       lsr.w    #4,d0             * /16, copying 4 longs at a time
  422.       sub.w    #1,d0
  423. s_next
  424.       move.l   -(a2),-(a1)
  425.       move.l   -(a2),-(a1)
  426.       move.l   -(a2),-(a1)
  427.       move.l   -(a2),-(a1)
  428.       dbra     d0,s_next         * Copy source to destination, backwards
  429.       rts
  430.  
  431.    section s.data
  432.  
  433. oldbios  dc.l  0                 * Old bios vector
  434. cvsav    dc.l  0                 * For saving con_state vector
  435. scrinfo  dc.l  0                 * (Copy of) screen info pointer
  436. botbase  dc.l  0                 * Ptr to lowest screen used
  437. topbase  dc.l  0                 * Ptr to highest screen used
  438. nullstr  dc.l  0
  439. argstr   dc.b  6,'second'
  440. progname dc.b '\AUTO\SCROLL.PRG',0
  441. hadesc   dc.b  0                 * Boolean: Was previous char an escape?
  442.  
  443.    end
  444.  
  445.  
  446.